useReact 19 推出了新的 API use ,可以用來取得非同步的內容或 Promise ,也可用來取得 Context。
use 只能在 render 期間使用,只能用在 Component 或 Hook 。需要注意的是 use 並不是 Hook,是可以在條件語句或迴圈使用的。
和 useContext 不同的是,use 可以在條件語句或迴圈使用。
function App({ show }) {
  if (show) {
    const theme = use(ThemeContext);
    return <SomeComponent theme={theme} />;
  }
  return null;
}
use 取得 Promise當使用 use 取得 Promise 時,通常會搭配 Suspense 和 ErrorBoundary。
範例:
import { use, Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";
export default function App() {
  const userPromise = db.connect.getUsers(id);
  return (
    <div>
      <ErrorBoundary fallback={<ErrorFallback />}>
        <Suspense fallback={<Loading />}>
          <UserList userPromise={userPromise} />
        </Suspense>
      </ErrorBoundary>
    </div>
  );
}
"use client";
function UserList({ userPromise }) {
  const users = use(userPromise);
  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
透過以上寫法就不用使用 useState 和 useEffect來處理資料狀態。
use 傳遞 Promise 注意事項通常會建議在 Server Components 中創建 Promise,並將 Promise 當作 props 傳遞給 Client Components ,並在 Client Component 中使用 use。
如果要在 Server Component 取得資料,使用 async和 await 就好,不需要使用 use,以下是兩者的差別:
async和 await 會在執行 await 時暫停渲染,直到 await 完成後會再繼續執行。use 會在取得資料後重新渲染元件。另外要注意的是不能在 render 的過程中創建的 Promise,應該使用已經創建好的 Promise。若在 render 中創建 Promise,會產生以下警告:
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.
範例說明:
const fetchUserData = () => {
  return fetch("https://example.com/users").then((res) => res.json());
};
const promiseFetchUserData = fetchUserData(); // 在外部創建 Promise
function UserList() {
  const data = use(fetchUserData()); //這樣會出現錯誤
  const data = use(promiseFetchUserData); // 正確用法
  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
在使用 use 時也需要錯誤處理。use 無法直接在 try-catch 中使用,通常要配合 ErrorBoundary。除此之外,也可以在 Promise 的 catch 中提供替代值。
const userPromise = new Promise((resolve, reject) => {
  reject();
}).catch(() => {
  return "no user"; // 提供的替代值
});
在沒有處理錯誤時,React 會讓畫面直接崩潰。目前在 Function Component 沒有辦法建立 ErrorBoundary,需要使用 react-error-boundary 套件來處理錯誤,當錯誤發生時會顯示 fallback 的 UI 內容。
參考資料:
https://react.dev/blog/2024/04/25/react-19
https://react.dev/reference/react/use#usage
https://www.youtube.com/watch?v=AJOGzVygGcY
https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary